#include "Interpreter.hpp"

int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, ParserContext *context)
{
	return context->yylex(lvalp, llocp);
}

int yyerror(YYLTYPE *locp, ParserContext *context, const char *msg)
{
	//TODO
	return 0;
}

int executeFile(const char *filename, ExecutionEnvironment *execEnv, Job *context)
{
	// Open the file
	FILE *fin = fopen(filename, "r");
	if(!fin) {
		context->reportError(retprintf("%s: File not found", filename).c_str());
		return EX_NOTFOUND;
	}
	
	// Read it all
	StreamBuffer buf;
	while(!feof(fin))
	{
		char *readbuf = (char*)buf.reserveSpace(512);
		int bytesRead = fread(readbuf, 1, 512, fin);
		if(bytesRead > 0)
			buf.appendReserved(bytesRead);
	}
	buf.appendByte(0);
	
	// Close up
	fclose(fin);
	
	// Parse and execute the file's contents
	return executeText(buf.getData(), execEnv, context);
}

int executeText(const char *cmd, ExecutionEnvironment *execEnv, Job *context)
{
	ParserContext parserContext(cmd, context->getState());
	
	int parseResult = yyparse(&parserContext);

	if(parseResult != 0)
	{
		context->reportError("Syntax error");
		return EX_BADSYNTAX;
	}
	
	bool background = false;
	if(parserContext.result->getRunInBackground())
	{
		context->setRunState(STATE_BACKGROUNDED, true);
	}
	
	ShellCommand *parsedCommand = parserContext.result;
	int result = parsedCommand->execute(execEnv, context);
	return result;
}

void interactiveParserTest()
{
	char buf[512];
	while(!feof(stdin))
	{
		bool first = true;
		string line = "";
		
		Tokenization tokenization(NULL);
		do {
			if(first) {
				printf("> ");
				first = false;
			} else {
				printf("  ");
			}
			buf[0] = 0;
			fgets(buf, 512, stdin);
			line += buf;
			tokenize(line.c_str(), &tokenization, CONTEXT_ROOT);
		} while(!feof(stdin) && tokenization.truncated);
		
		ParserContext parseContext(line.c_str(), NULL);
		int parseResult = yyparse(&parseContext);
		
		string tokStr = tokenizationToString(parseContext.getTokenization());
		puts(tokStr.c_str());
		
		if(parseResult==0) {
			ShellCommand *parsedCommand = parseContext.result;
			string output = parsedCommand->toString();
			puts(output.c_str());
		} else {
			puts("Syntax error");
		}
	}
}

